/**
 * @brief Biblioteca de álgebra de vetores
 *
 * @author Thales Luis Rodrigues Sabino
 * @date   2009
 */


#include "mcVector.h"


using namespace mc;


/**
 * @brief Construtor padrão. Constroi um vetor com o valor t
 *
 * @param t - Valor para ser setado em todas as componentes
 */
//template <class T>
//vec2<T>::vec2( const T &t ) {
//    this->x = t;
//    this->y = t;
//}

/**
* @brief Constrói a partir de um array
*
* @param a - Array para construir o vetor
*/
//template <class T>
//vec2<T>::vec2( const T *a ) {
//    this->x = a[0];
//    this->y = a[1];
//}


/**
 * @brief Constrói um vetor explicitamente
 *
 * @param x - Compomente X
 * @param y - Componente Y
 */
//template <class T>
//vec2<T>::vec2( const T x, const T y ) {
//    this->x = x;
//    this->y = y;
//}

/**
 * @brief Constrói por cópia
 *
 * @param v - Vetor a ser copiado
 */
//template <class T>
//vec2<T>::vec2( vec2<T> &v ) {
//    this->x = v.x;
//    this->y = v.y;
//}

//template <class T>
//vec2<T>::vec2( vec3<T> &v ) {
//    this->x = v.x;
//    this->y = v.y;
//}

//template <class T>
//vec2<T>::vec2( vec4<T> &v ) {
//    this->x = v.x;
//    this->y = v.y;
//}


/**
 * @brief Operador [] para acesso ao vetor
 *
 * @param i - Índice de acesso
 */
template <class T>
T& vec2<T>::operator [] ( int i ) {
    assert( i >= 0 && i < this->size() );
    return this->_array[i];
}


/**
 * @brief Operador soma de dois vetores
 *
 * @param v1
 * @param v2
 */
template <class T>
vec2<T>& vec2<T>::operator + ( const vec2<T> &v ) {
    vec2<T> *vr = new vec2<T>();
    vr->x = this->x + v.x;
    vr->y = this->y + v.y;
    return *vr;
}


/**
 * @brief Operador subtração de dois vetores
 *
 * @param v1
 * @param v2
 */
template <class T>
vec2<T>& vec2<T>::operator - ( const vec2<T> &v ) {
    vec2<T> *vr = new vec2<T>();
    vr->x = this->x - v.x;
    vr->y = this->y - v.y;
    return *vr;
}


/**
 * @brief Operador multiplicação de componentes de dois vetores
 *
 * @param v1
 * @param v2
 */
template <class T>
vec2<T>& vec2<T>::operator * ( const vec2<T> &v ) {
    vec2<T> *vr = new vec2<T>();
    vr->x = this->x * v.x;
    vr->y = this->y * v.y;
    return *vr;
}


/**
 * @brief Operador divisão de compomentes de dois vetores
 *
 * @param v1
 * @param v2
 */
template <class T>
vec2<T>& vec2<T>::operator / ( const vec2<T> &v ) {
    vec2<T> *vr = new vec2<T>();
    vr->x = this->x / v.x;
    vr->y = this->y / v.y;
    return *vr;
}


/**
 * @brief Operador de escalamento
 *
 * @param v - Vetor a ser escalado
 * @param s - Fator de escala
 */
template <class T>
vec2<T>& vec2<T>::operator * ( const T s ) {
    vec2<T> *vr = new vec2<T>();
    vr->x = this->x * s;
    vr->y = this->y * s;
    return *vr;
}


/**
 * @brief Operador de escalamento
 *
 * @param v - Vetor a ser escalado
 * @param s - Fator de escala
 */
template <class T>
vec2<T>& vec2<T>::operator / ( const T s ) {
    vec2<T> *vr = new vec2<T>();
    vr->x = this->x / s;
    vr->y = this->y / s;
    return *vr;
}


/**
 * @brief Acumulador +=
 *
 * @param v
 */
template <class T>
vec2<T>& vec2<T>::operator += ( const vec2<T> &v ) {
    this->x += v.x;
    this->y += v.y;
    return *this;
}


/**
 * @brief Acumulador -=
 *
 * @param v
 */
template <class T>
vec2<T>& vec2<T>::operator -= ( const vec2<T> &v ) {
    this->x -= v.x;
    this->y -= v.y;
    return *this;
}


/**
 * @brief Acumulador *=
 *
 * @param v
 */
template <class T>
vec2<T>& vec2<T>::operator *= ( const vec2<T> &v ) {
    this->x *= v.x;
    this->y *= v.y;
    return *this;
}

/**
 * @brief Acumulador /=
 *
 * @param v
 */
template <class T>
vec2<T>& vec2<T>::operator /= ( const vec2<T> &v ) {
    this->x /= v.x;
    this->y /= v.y;
    return *this;
}
